在前一篇的demo中,我們了解到Sentry在NodeJS+express的應用中,是用Sentry.setupExpressErrorHandler(app)
來獲取應用中的錯誤。那麼為何要在所有controller之後才呼叫Sentry的錯誤處理中間件呢?這就要聊到express middleware的機制。
一般來說,middleware可以分為三種主要類型:
例如常見的
app.use(express.json()); // 處理 JSON body
app.use(cors()); // 處理 CORS
app.use(logger('dev')); // 請求日誌
這些通常會放在controller之前,因為無論是什麼路由,這些操作都需要執行。
這些 middleware 只應用於某些路由,比如身份驗證、權限檢查或自定義邏輯處理。這些 middleware 可以和路由處理器一起使用,放置在相應的路由之前。
// 只對 `/admin` 路由進行身份驗證
app.use('/admin', authenticateAdmin);
app.get('/admin/dashboard', (req, res) => {
res.send('Welcome to the admin dashboard');
});
這類 middleware 必須放在所有路由和其他 middleware 之後,因為它需要捕捉前面的 controller 或 middleware 未處理的錯誤。放在最後確保錯誤可以被集中處理,避免應用崩潰。
// 所有路由和controller之後
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
所以Sentry.setupExpressErrorHandler(app);
才需要放在所有controller之後,為了就是收集所有錯誤、並上傳到Sentry。
既然了解 Sentry.setupExpressErrorHandler
就是express middleware的使用,就可以簡單寫一個了:
class SelfSentry {
static setupExpressErrorHandler(expressApp) {
expressApp.use(this._expressErrorHandler());
}
static _expressErrorHandler() {
return (err, req, res, next) => {
// 這邊就是處理Sentry上報error的邏輯,目前先console出來
console.log('----in SelfSentry error middleware');
console.error(err.stack);
next(error);
};
}
}
module.exports = {
SelfSentry,
};
然後我們來demo看看,運行看看有沒有捕捉到:
const express = require('express');
const cors = require('cors');
const { SelfSentry } = require('./self-sentry');
const app = express();
const PORT = 3060;
app.use(cors());
app.get('/', (req, res) => {
res.send('hello self error catcher');
});
app.get('/demo-error', (req, res) => {
throw new Error('---Mock Error');
});
SelfSentry.setupExpressErrorHandler(app);
app.listen(PORT, () => {
console.log(`server on http://localhost:${PORT}`);
});
terminal console:
可以看到拋出的Mock Error
已經被我們的錯誤捕捉middleware給捕獲、並console出來。
今天這一篇,我們手寫了一個sdk,仿照Sentry的方式宣告、並成功捕獲了錯誤。本文的完成程式碼可以查看Github repository
接下來,我們將聊聊Sentry對後端服務的性能監控。
packages/node/src/integrations/tracing/express.ts